package cn.edu.fudan.type;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 80494 on 2017/4/3.
 * this is one of wavelet presentation of a time series in each order
 *
 */
public class WaveletPerOrder {


    private List<Integer> order ;
    private List<List<Double>> series;
    private List<List<Integer>> dseries; //细节
    private List<List<Double>> coeff;
    private List<List<Integer>> djseries;//轮廓
    private int label;

    public WaveletPerOrder (){
        this.order= new ArrayList<>();
        this.coeff = new ArrayList<>();
        this.series = new ArrayList<>();
        this.dseries = new ArrayList<>();
        this.djseries = new ArrayList<>();
        for (List<Double> T:this.series) {
            T = new ArrayList<>();
        }
        for (List<Double> T:this.coeff) {
            T = new ArrayList<>();
        }
        for (List<Integer> T:this.dseries) {
            T = new ArrayList<>();
        }
        for (List<Integer> T:this.djseries) {
            T = new ArrayList<>();
        }
        this.label = 0;
        /*for (int R:this.order) {
            R=0;
        }
        for(ArrayList<Double> R:this.coeff){
            for (Double T:R) {
                T=0.0;
            }
        }
        for(ArrayList<Double> R:this.series){
            for (Double T:R) {
                T=0.0;
            }
        }
        for(ArrayList<Integer> R:this.dseries){
            for (Integer T:R) {
                T=0;
            }
        }*/
    }

    /*
public WaveletPerOrder (int o, int length){
        this.order= new ArrayList<>(o);
        this.coeff = new ArrayList<>(o);
        this.series = new ArrayList<>(o);
        this.dseries = new ArrayList<>(o);
        for (List<Double> T:this.series) {
            T = new ArrayList<>(length);
        }
        for (List<Double> T:this.coeff) {
            T = new ArrayList<>(length);
        }
        for (List<Integer> T:this.dseries) {
            T = new ArrayList<>(length);
        }
        this.label = 0;
        /*for (int R:this.order) {
            R=0;
        }
        for(ArrayList<Double> R:this.coeff){
            for (Double T:R) {
                T=0.0;
            }
        }
        for(ArrayList<Double> R:this.series){
            for (Double T:R) {
                T=0.0;
            }
        }
        for(ArrayList<Integer> R:this.dseries){
            for (Integer T:R) {
                T=0;
            }
        }
}
 */



    public void setOrder(List<Integer> order){
        this.order = order;
    }
    public void setSeries(List<List<Double>> series){
        this.series =series;
    }
    public void setDseries(List<List<Integer>> dseries){
        this.dseries =dseries;
    }
    public void setCoeff(List<List<Double>> coeff){
        this.coeff =coeff;
    }
    public void setDjseries(List<List<Integer>> djseries){
        this.djseries =djseries;
    }
    public void setLabel(int label){
        this.label =label;
    }


    public List<Integer> getOrder(){
        return order;
    }
    public List<List<Double>> getSeries(){
        return series;
    }
    public List<List<Integer>> getDseries(){
        return dseries;
    }
    public List<List<Double>> getCoeff(){
        return coeff;
    }
    public int getLabel(){
        return label;
    }
    public List<List<Integer>> getDjseries(){
        return djseries;
    }

    public List<Integer> addOrder(Integer O, int index){
        order.add(index,0);
        return order;
    }
    public List<List<Double>> addSeries(List<Double> S,int index){
        series.add(index,S);
        return series;
    }
    public List<List<Integer>> addDseries(List<Integer> DS,int index) {
        dseries.add(index,DS);
        return dseries;
    }
    public List<List<Integer>> addDjseries(List<Integer> DJ,int index) {
        dseries.add(index,DJ);
        return djseries;
    }

    public List<List<Double>> addCoeff(List<Double> C,int index){
        coeff.add(index,C);
        return coeff;
    }



    public List<Integer> SeriesToDseries(List<Double> aseries, int n, Double min ,Double max){
        List<Double> NSeries =new ArrayList<>();
        List<Integer> DSeries = new ArrayList<>();
        for (int i=0;i<aseries.size();i++){                      //对小波变换后的序列进行标准化到-0.5和0.5之间
            NSeries.add(i,((aseries.get(i)-min)/(max-min)));
        }

        for (int a =0;a<aseries.size();a++) {
            for(int j=0;j<n;j++){
                if (rangeInDefined(NSeries.get(a),(-0.5+(double)j/(double)n),(-0.5+((double)j+1)/(double)n))){
                    DSeries.add(a,j);
                    break;
                }

            }
        }
        return DSeries;
    }

    public List<Double> SeriesToSeries(List<Double> aseries){
        List<Double> bseries = new ArrayList<>();
        for(int k=0;k<(aseries.size()+1)/2;k++){
            bseries.add(k,(aseries.get(2*k)+aseries.get(2*k+1))/2);
        }
        return bseries;
    }

    public List<Double> SeriesToCoeff(List<Double> aseries){
        List<Double> bseries = new ArrayList<>();
        for(int k=0;k<(aseries.size()+1)/2;k++){
            bseries.add(k,(aseries.get(2*k+1)-aseries.get(2*k))/2);
        }
        return bseries;
    }

    public static boolean rangeInDefined(Double current, Double Amin,Double Amax) {
        return Math.max(Amin,current)==Math.min(current,Amax);
    }
    @Override
    public String toString(){
        return   "［Order: "+order+",　series: "+series+"， coeff:"  +coeff+", label:"+label +", dseries"+dseries+"]";
    }
}
